package JAVA克隆;


/**
 * 项目名称：Demo01
 * 类 名 称：CloneDemo
 * 类 描 述：TODO
 * 创建时间：2021/03/15 14:30
 * 创 建 人：XiaoCoder
 */
public class CloneDemo {
    /*
        浅克隆：创建一个新对象，新对象的属性和原来对象完全相同，对于非基本类型属性，仍指向原有属性所指向的对象的内存地址（简称不是完全复制）。
        深克隆：创建一个新对象，属性中引用的其他对象也会被克隆，不再指向原有对象地址。（完全复制）
        clone步骤：
            1. 被复制的类需要实现Clonenable接口（不实现的话在调用clone方法会抛出CloneNotSupportedException异常)，
                该接口为标记接口(不含任何方法)
            2. 覆盖clone()方法，访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。（native为本地方法)
     */
    public static void main(String[] args) throws Exception {
        // 浅拷贝
        //ShallowClone();
        // 深拷贝
        DeepClone();
    }

    /**
     * 浅克隆
     */
    protected static void ShallowClone() throws Exception {
        CloneEntity entity = new CloneEntity();
        entity.setId(1);
        entity.setName("xiao");
        CloneEntity entity1 = (CloneEntity) entity.clone();

        System.out.println("clone1:" + entity.getId());
        System.out.println("clone2:" + entity1.getId());

        entity1.setId(2);

        /*
            clone1:1
            clone2:1
            clone1:1hashcode:1735600054  地址值：JAVA克隆.CloneEntity@677327b6
            clone2:2hashcode:21685669  地址值：JAVA克隆.CloneEntity@14ae5a5
            所以是两个对象！
        */

        System.out.println("clone1:" + entity.getId() + "hashcode:" + entity.hashCode() + "  地址值：" + entity);
        System.out.println("clone2:" + entity1.getId() + "hashcode:" + entity1.hashCode() + "  地址值：" + entity1);
    }

    /**
     * 深拷贝
     *
     * @throws Exception
     */
    protected static void DeepClone() throws Exception {
        CloneEntity cloneEntity = new CloneEntity();
        cloneEntity.setId(1);
        cloneEntity.setName("xiao");
        CloneEntitySenior entitySenior = new CloneEntitySenior();
        entitySenior.setNum(123);
        entitySenior.setCloneEntity(cloneEntity);

        // 进行深拷贝
        CloneEntitySenior entitySenior1 = (CloneEntitySenior) entitySenior.clone();

        System.out.println("cloneEntity(id):" + entitySenior.getCloneEntity().getId() + ",entitySenior(num):" + entitySenior.getNum());
        System.out.println("cloneEntity(id):" + entitySenior1.getCloneEntity().getId() + ",entitySenior(num):" + entitySenior1.getNum());

        //修改非基本类型中的属性
        cloneEntity.setId(2);
        /*
            结果：可以看出深克隆中的对象和clone的本体对象中的非基本类型中的属性并没有同时改变；
            cloneEntity(id):1,entitySenior(num):123
            cloneEntity(id):1,entitySenior(num):123
            cloneEntity(id):2,entitySenior(num):123
            cloneEntity(id):1,entitySenior(num):123
        */
        System.out.println("cloneEntity(id):" + entitySenior.getCloneEntity().getId() + ",entitySenior(num):" + entitySenior.getNum());
        System.out.println("cloneEntity(id):" + entitySenior1.getCloneEntity().getId() + ",entitySenior(num):" + entitySenior1.getNum());

    }

}
